package com.jdyfy.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jdyfy.entity.AllFile;
import com.jdyfy.mapper.FileMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;


/**
 * 文件
 */
@Slf4j
@RestController
@RequestMapping("/jdyfy/file")
public class FileController {

    @Resource
    private FileMapper fileMapper;

    @Value("${files.upload.path}")
    private String fileUploadPath;//拿到文件的路径

    @Value("${server.ip}")
    private String serverIp;//拿到文件的路径

    /**
     * 文件上传
     * @param file 前端传递过来的文件
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file,
                         @RequestParam(value = "fileRole", required = false) String fileRole,
                         @RequestParam(value = "departmentName", required = false) String departmentName
                         ) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String type = FileUtil.extName(originalFilename);
        long size = file.getSize();

        //定义一个文件唯一的标识符
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = uuid + "." + type;

        File uploadFile = new File(fileUploadPath + fileUUID);
        //判断路径下是否有该文件夹,不存在创建一个新的文件夹
        File parentFile = uploadFile.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }

        String md5;
        String url;
        //保存文件到磁盘
        file.transferTo(uploadFile);
        //获取文件的md5
        md5 = SecureUtil.md5(uploadFile);
        //判断数据库中是否存在相同的记录
        AllFile dbFile = getFileByMd5(md5);
        if (dbFile != null) {
            url = dbFile.getFileUrl();
            //由于文件已存在，删除刚才上传的文件
            uploadFile.delete();
        } else {
            //文件第一次上传保存到数据库
            url = "http://" + serverIp + ":8081/jdyfy/file/download/" + fileUUID;
        }

        //保存到数据库
        AllFile savaFile = new AllFile();
        savaFile.setFileName(originalFilename);
        savaFile.setFileType(type);
        savaFile.setFileSize(size/1024);//b转kb
        savaFile.setFileUrl(url);
        savaFile.setMd5(md5);
        if(fileRole != null){
            savaFile.setFileRole(fileRole);
        }
        fileMapper.insert(savaFile);

        return url;
    }

    /**
     * 文件下载  http://localhost:8081/jdyfy/file/download/{fileUUID}
     * @param fileUUID 文件唯一标识
     * @param response 响应对象
     * @throws IOException
     */
    @GetMapping("/download/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        // 根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        // 设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        // 读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }


    /**
     * 根据md5查询文件
     * @param md5
     * @return
     */
    private AllFile getFileByMd5(String md5) {
        //根据md5判断文件是否已经存在
        QueryWrapper<AllFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",md5);
        List<AllFile> allFileList = fileMapper.selectList(queryWrapper);
        return allFileList.size() == 0 ? null : allFileList.get(0);
    }


}
